package com.icongyou.enterprise.talent_analysis.event;

import com.icongyou.enterprise.talent_analysis.service.AIInsightCacheService;
import com.icongyou.enterprise.talent_analysis.service.PortraitAsyncService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

/**
 * 学生数据变更事件监听器测试
 */
@ExtendWith(MockitoExtension.class)
@DisplayName("学生数据变更事件监听器测试")
class StudentDataChangeListenerTest {

    @Mock
    private PortraitAsyncService portraitAsyncService;

    @Mock
    private AIInsightCacheService aiInsightCacheService;

    @InjectMocks
    private StudentDataChangeListener listener;

    @Test
    @DisplayName("handleDataChange - 触发画像更新和缓存失效")
    void testHandleDataChange_Success() {
        // Arrange - 必须提供sourceId，否则会拼接null
        StudentDataChangeEvent event = new StudentDataChangeEvent(
            this, "660e8400-e29b-41d4-a716-446655440105", "SUBMISSION_CREATED", "submission-123"
        );

        // Act
        listener.handleDataChange(event);

        // Assert
        verify(portraitAsyncService).triggerStudentPortraitUpdate(
            eq("660e8400-e29b-41d4-a716-446655440105"), 
            eq("SUBMISSION_CREATED:submission-123")
        );
        verify(aiInsightCacheService).invalidateStudentCache("660e8400-e29b-41d4-a716-446655440105");
    }

    @Test
    @DisplayName("handleDataChange - 不同变更类型")
    void testHandleDataChange_DifferentChangeTypes() {
        // Arrange - 成绩更新
        StudentDataChangeEvent gradeEvent = new StudentDataChangeEvent(
            this, "660e8400-e29b-41d4-a716-446655440105", "GRADE_UPDATED", "grade-456"
        );

        // Act
        listener.handleDataChange(gradeEvent);

        // Assert
        verify(portraitAsyncService).triggerStudentPortraitUpdate(
            eq("660e8400-e29b-41d4-a716-446655440105"), 
            eq("GRADE_UPDATED:grade-456")
        );
        verify(aiInsightCacheService).invalidateStudentCache("660e8400-e29b-41d4-a716-446655440105");
    }

    @Test
    @DisplayName("handleDataChange - 画像更新失败不影响缓存失效")
    void testHandleDataChange_PortraitUpdateFails() {
        // Arrange
        StudentDataChangeEvent event = new StudentDataChangeEvent(
            this, "660e8400-e29b-41d4-a716-446655440105", "SUBMISSION_CREATED", "sub-789"
        );
        
        doThrow(new RuntimeException("画像更新失败"))
            .when(portraitAsyncService)
            .triggerStudentPortraitUpdate(anyString(), anyString());

        // Act & Assert - 异常会传播出来
        try {
            listener.handleDataChange(event);
        } catch (RuntimeException e) {
            // 预期会抛出异常
        }

        // Assert - 只验证画像更新被调用了
        verify(portraitAsyncService).triggerStudentPortraitUpdate(
            eq("660e8400-e29b-41d4-a716-446655440105"), 
            eq("SUBMISSION_CREATED:sub-789")
        );
        // 因为异常，缓存失效不会被调用
        verify(aiInsightCacheService, never()).invalidateStudentCache(anyString());
    }

    @Test
    @DisplayName("handleDataChange - 包含sourceId的事件")
    void testHandleDataChange_WithSourceId() {
        // Arrange
        StudentDataChangeEvent event = new StudentDataChangeEvent(
            this, "660e8400-e29b-41d4-a716-446655440105", "SUBMISSION_CREATED", "submission-123"
        );
        
        doNothing().when(portraitAsyncService)
            .triggerStudentPortraitUpdate(anyString(), anyString());
        doNothing().when(aiInsightCacheService)
            .invalidateStudentCache(anyString());

        // Act
        listener.handleDataChange(event);

        // Assert
        verify(portraitAsyncService).triggerStudentPortraitUpdate(
            eq("660e8400-e29b-41d4-a716-446655440105"), 
            eq("SUBMISSION_CREATED:submission-123")
        );
        verify(aiInsightCacheService).invalidateStudentCache("660e8400-e29b-41d4-a716-446655440105");
    }

    @Test
    @DisplayName("handleDataChange - 批量事件处理")
    void testHandleDataChange_MultipleEvents() {
        // Arrange
        StudentDataChangeEvent event1 = new StudentDataChangeEvent(
            this, "660e8400-e29b-41d4-a716-446655440105", "SUBMISSION_CREATED", "sub-1"
        );
        StudentDataChangeEvent event2 = new StudentDataChangeEvent(
            this, "660e8400-e29b-41d4-a716-446655440103", "GRADE_UPDATED", "grade-2"
        );

        // Act
        listener.handleDataChange(event1);
        listener.handleDataChange(event2);

        // Assert
        verify(portraitAsyncService).triggerStudentPortraitUpdate(
            eq("660e8400-e29b-41d4-a716-446655440105"), 
            eq("SUBMISSION_CREATED:sub-1")
        );
        verify(portraitAsyncService).triggerStudentPortraitUpdate(
            eq("660e8400-e29b-41d4-a716-446655440103"), 
            eq("GRADE_UPDATED:grade-2")
        );
        verify(aiInsightCacheService).invalidateStudentCache("660e8400-e29b-41d4-a716-446655440105");
        verify(aiInsightCacheService).invalidateStudentCache("660e8400-e29b-41d4-a716-446655440103");
    }
}
